<template>
	<div class="explore_container">
		<div class="no_chat" v-if="list.length == 0">
			<div class="logo">
				<div>
					<img :src="agent.icon" v-if="(Type == 1 || Type == 2) && agent.icon" style="width: 6.67rem; height: 6.67rem" />
					<logo width="6.67rem" height="6.67rem" v-else></logo>
					<div class="name" v-if="Type == 1 || Type == 2">{{ agent.name }}</div>
				</div>
				<div class="logo_right" v-if="Type == 1 || Type == 2">
					<div @click="gotoAgent" style="cursor: pointer" v-if="Type == 2">
						<Edit width="1.33rem" height="1.33rem"></Edit>
					</div>
					<Poptip trigger="hover" placement="right">
						<ChaKan width="1.53rem" height="1.53rem"></ChaKan>
						<div slot="content" class="pop_content">
							<div class="title">角色描述</div>
							<div>{{ agent.role }}</div>
							<div class="title">开场白</div>
							<div>{{ agent.opening }}</div>
						</div>
					</Poptip>
				</div>
			</div>
			<div class="desc">{{ agent.opening }}</div>
			<ul class="suggest_list">
				<li v-for="(item, index) in agent.suggestionList" :key="index" @click="handelSug(item)"><span class="dot"></span> {{ item }}</li>
			</ul>
		</div>
		<div class="chat_list" v-else ref="chatList">
			<div v-for="(item, index) in list" :key="index">
				<div v-if="item.chatType == ChatType.user">
					<user :message="item" :index="index" category="explore" :currentIndex="currentIndex - 1" @on-delete="delChatDetail" @on-edit="editPrompt"></user>
				</div>
				<div v-else-if="item.chatType == ChatType.robot">
					<robot
						:ref="'robot_' + index"
						:message="item"
						:index="index"
						category="explore"
						:currentIndex="currentIndex"
						@on-resend="resendMsg"
						@on-clear-context="clearContext(index)"
						@on-like="dolike(index)"
						@on-unlike="dounlike(index)"
						@on-suggestion="handelSug"
						@on-delete="delChatDetail"
						@on-audio="handelAudio(index)"
					></robot>
				</div>
				<div class="clearContext" v-else-if="item.chatType == ChatType.clear">
					<Divider>已清除上下文</Divider>
				</div>
			</div>
		</div>
		<div class="chat_bottom">
			<div class="tool">
				<div class="tool_btn" @click="getInspiration">
					<LingGan width="1.5rem" height="1.5rem"></LingGan>
					<span>聊天灵感</span>
				</div>
			</div>
			<div class="input_container" v-show="!isVoice">
				<Input v-model="inputStr" type="textarea" placeholder="您可以在此输入您的问题或点击麦克风图标进行语音输入" maxlength="2000" @keydown.native="KeyDownFn" />
				<!-- <img :src="videoIcon"  width="24" /> -->
				<div class="yuyin" @click="startVoice">
					<YuYin width="1.5rem" height="1.5rem"></YuYin>
				</div>
			</div>
			<div class="voice_bg" v-show="isVoice">
				<!-- <img class="pausebtn" :src="pausedIcon" width="24" @click="pauseVoice" /> -->
				<div class="pausebtn" @click="pauseVoice">
					<YuYin2 width="1.5rem" height="1.5rem"></YuYin2>
				</div>
				<div class="voice_content">{{ inputStr }}</div>
				<div class="voice_loading">
					<!-- <img :src="voiceLoadingIcon" height="18" /> -->
					<YuYin3 width="4.5rem" height="1.13rem"></YuYin3>
					<span>正在倾听中.......</span>
				</div>
			</div>
			<div class="bottom_btn">
				<Button @click="send">发送</Button>
			</div>
			<div class="footer">
				<span>对话内容由AI生成，仅供参考</span>
			</div>
		</div>
	</div>
</template>
<script>
import Logo from '@/components/svg/logo.vue'
import LingGan from '@/components/svg/linggan.vue'
import YuYin from '@/components/svg/yuyin.vue'
import YuYin3 from '@/components/svg/yuyin3.vue'
import YuYin2 from '@/components/svg/yuyin2.vue'
import ChaKan from '@/components/svg/chakan.vue'
import Edit from '@/components/svg/v1/edit.vue'
import { ChatType } from '../chat/components/util'
import Robot from '../chat/components/robot.vue'
import User from '../chat/components/user.vue'
import { xiaoxieGuID } from '@/libs/util'
import { EventBus } from '@/libs/eventbus'
import Clipboard from 'clipboard'
export default {
	data() {
		return {
			defaultsuggest: ['打开机械革命电竞控制台', '把电脑的音量设置为20', '我需要写一封商务合作邮件，你能帮我构思一下内容吗？', '游戏中作为英勇战士，你通常如何与队友沟通并制定战术？'],
			defaultopening: '你的个人专属AI智能体，初次见面很开心呢！我可以回答你的各种问题，给你的娱乐、工作和学习提供帮助，还能随时陪你聊天。嗯，你想问点什么呢？',
			agent: {
				name: '',
				opening: '',
				suggestionList: [],
				role: '',
				welcome: '',
				icon: ''
			},
			inputStr: '',
			list: [],
			hisList: [],
			isloading: false,
			currentIndex: 0,
			currentMsg: '',
			ChatType: ChatType,
			isVoice: false,
			timer: null,
			count: 60,
			agentId: '',
			chatId: '',
			Type: 0
		}
	},
	components: {
		Logo,
		YuYin,
		YuYin3,
		YuYin2,
		ChaKan,
		LingGan,
		Edit,
		Robot,
		User
	},
	watch: {
		$route(to, from) {
			console.log(this.$route.query.id)
			this.chatId = this.$route.query.id
			if (this.$route.query.type) {
				this.Type = this.$route.query.type
			} else {
				this.Type = 0
			}
			if (this.$route.query.agentId) {
				this.agentId = this.$route.query.agentId
			}
			setTimeout(async () => {
				await this.initChat()
			}, 0)
		},
		list: {
			handler(newVal, oldVal) {
				this.scrollToBottom()
			},
			deep: true
		},
		isloading(val) {
			EventBus.$emit('setLoadingState', val)
		}
	},
	// 在数据更新时，重新创建 Clipboard 实例
	updated() {
		if (this.clipboardCode) {
			this.clipboardCode.destroy()
		}
		this.createClipboardInstance()
	},
	methods: {
		createClipboardInstance() {
			this.clipboardCode = new Clipboard('.copy-btn')
			this.clipboardCode.on('success', (e) => {
				e.clearSelection()
				this.$Message.success({
					content: '复制成功'
				})
			})
			this.clipboardCode.on('error', () => {
				this.$Message.error({
					content: '复制失败'
				})
			})
		},
		handelSug(obj) {
			this.inputStr = obj
		},
		async startVoice() {
			this.inputStr = ''
			this.dotimer()
			await chrome.webview.hostObjects.form.OnPageEvent('startRecord')
		},
		async stopVoice() {
			await chrome.webview.hostObjects.form.OnPageEvent('stopRecord')
		},
		pauseVoice() {
			this.isVoice = false
			if (this.timer) {
				clearInterval(this.timer)
				this.timer = null
			}
			this.stopVoice()
		},
		dotimer() {
			let TIME_COUNT = 60
			if (!this.timer) {
				this.count = TIME_COUNT
				this.isVoice = true
				this.timer = setInterval(() => {
					if (this.count > 0 && this.count <= TIME_COUNT) {
						this.count -= 1
					} else {
						this.isVoice = false
						clearInterval(this.timer)
						this.timer = null
						this.stopVoice()
					}
				}, 1000)
			}
		},
		send() {
			if (!this.inputStr || !this.inputStr.trim()) {
				return false
			} else {
				this.sendMessage(this.inputStr.trim())
				this.inputStr = ''
			}
		},
		sendMessage(msg) {
			if (!this.isloading) {
				this.list.push({
					chatType: ChatType.user,
					id: '',
					content: msg
				})
				this.currentMsg = msg
				this.getAnswer(msg)
			} else {
				this.$Message.error('请等机器人回复后再发送哦~')
			}
		},
		async getAnswer(msg) {
			this.isloading = true
			this.list.push({
				chatType: ChatType.robot,
				content: '',
				id: '',
				suglist: [],
				islike: false,
				isunlike: false,
				isLoading: true
			})
			this.currentIndex = this.list.length - 1
			let hisList = this.getHisList()
			hisList.push({
				role: 'user',
				content: msg
			})
			if (this.chatId === xiaoxieGuID) {
				let res = await chrome.webview.hostObjects.chatHelper.SendChatAsync(JSON.stringify(hisList))
				res = JSON.parse(res)
				if (res.code === '0') {
					this.list[this.currentIndex].id = res.data
					if (this.list[this.currentIndex - 1].chatType === ChatType.user) {
						this.list[this.currentIndex - 1].id = res.data
					}
				} else {
					this.list[this.currentIndex].isLoading = false
					this.isloading = false
					this.list[this.currentIndex].content = res.data
				}
			} else {
				let res = await chrome.webview.hostObjects.chatHelper.ChatByChatIdAsync(this.chatId, JSON.stringify(hisList))
				res = JSON.parse(res)
				if (res.code === '0') {
					this.list[this.currentIndex].id = res.data
					if (this.list[this.currentIndex - 1].chatType === ChatType.user) {
						this.list[this.currentIndex - 1].id = res.data
					}
				} else {
					this.list[this.currentIndex].isLoading = false
					this.isloading = false
					this.list[this.currentIndex].content = res.data
				}
			}
		},
		scrollToBottom() {
			this.$nextTick(() => {
				let scrollElem = this.$refs.chatList
				scrollElem.scrollTo({ top: scrollElem.scrollHeight, behavior: 'smooth' })
			})
		},
		async getSuggestionList() {
			let hisList = this.getHisList()
			try {
				let result = await chrome.webview.hostObjects.chatHelper.RecommendAsync(JSON.stringify(hisList))
				result = JSON.parse(result)
				if (result instanceof Object) {
					let recommends = Object.values(result)
					this.list[this.currentIndex].suglist = recommends
					// localSave('chatlist', JSON.stringify(this.list))
				}
			} catch (e) {}
		},
		receiveMessage(content) {
			if (content === 'data: [DONE]') {
				this.list[this.currentIndex].isLoading = false
				this.isloading = false
				// localSave('chatlist', JSON.stringify(this.list))
				this.hisList = [...this.list]
				if (this.Type === 3 && this.currentIndex === 1) {
					this.GenerateTitle()
				}
				this.getSuggestionList()
			} else {
				this.list[this.currentIndex].content += content
			}
		},
		resendMsg() {
			this.getAnswer(this.currentMsg)
		},
		getHisList() {
			// let localList = localRead('chatlist')
			let hisList = []
			// if (localList) {
			let local = [...this.hisList]
			let index = local.findLastIndex((x) => x.chatType === ChatType.clear)
			let list = index === -1 ? [...local] : local.slice(index + 1)
			list.forEach((item) => {
				if (item.chatType === ChatType.user) {
					hisList.push({
						role: 'user',
						content: item.content
					})
				} else if (item.chatType === ChatType.functionCall) {
					hisList.push(item.tollcall)
				} else if (item.chatType === ChatType.robot) {
					hisList.push({
						role: 'assistant',
						content: item.content
					})
				}
			})
			// }
			return hisList
		},
		async clearContext(index) {
			this.list.push({
				chatType: ChatType.clear
			})
			this.hisList = [...this.list]
			await chrome.webview.hostObjects.chatHelper.ClearContextAsync(this.list[index].chatId)
			// this.getChatList()
			// localSave('chatlist', JSON.stringify(this.list))
		},
		setVoiceText(content) {
			this.inputStr = content
		},
		async dolike(index) {
			await chrome.webview.hostObjects.chatHelper.AddLikeAsync(this.list[index].id)
			this.list[index].islike = !this.list[index].islike
		},
		async dounlike(index) {
			await chrome.webview.hostObjects.chatHelper.AddDislikeAsync(this.list[index].id)
			this.list[index].isunlike = !this.list[index].isunlike
		},
		async getChatList() {
			this.isloading = true
			let res
			if (this.chatId === xiaoxieGuID) {
				res = await chrome.webview.hostObjects.chatHelper.QueryXiaoXieChatMsgsAsync()
				if (JSON.parse(res).length === 0) {
					this.list = []
					this.hisList = []
				} else {
					this.renderChatList(JSON.parse(res))
				}
			} else {
				res = await chrome.webview.hostObjects.chatHelper.QueryChatDetailsAsync(this.chatId)
				res = JSON.parse(res)
				if (res.code === '0') {
					if (res.data.length === 0) {
						this.list = []
						this.hisList = []
					} else {
						this.renderChatList(res.data)
					}
				}
			}
			await this.getAgentInfo()
			this.isloading = false
		},
		renderChatList(result) {
			console.log(result)
			let list = []
			result.forEach((item) => {
				list.push({
					chatType: ChatType.user,
					content: item.prompt,
					in_context: item.in_context,
					id: item.id
				})
				list.push({
					chatType: ChatType.robot,
					content: item.completion,
					suglist: [],
					islike: item.zan,
					isunlike: item.cai,
					isLoading: false,
					id: item.id,
					chatId: item.chat_id,
					in_context: item.in_context,
					createDate: item.create_datetime
				})
			})
			this.list = [...list]
			// 处理上下文
			let idx = this.list.findLastIndex((x) => !x.in_context)
			if (idx !== -1) {
				this.list.splice(idx + 1, 0, {
					chatType: ChatType.clear
				})
			}
			this.currentIndex = this.list.findLastIndex((x) => x.chatType === ChatType.robot)
			let lastidx = this.list.findLastIndex((x) => x.chatType === ChatType.user)
			this.currentMsg = this.list[lastidx].content
			this.hisList = [...this.list]
			this.getSuggestionList()
		},
		async GenerateTitle() {
			let hisList = this.getHisList()
			let res = await chrome.webview.hostObjects.chatHelper.GenerateTitleAsync(this.chatId, JSON.stringify(hisList))
			res = JSON.parse(res)
			if (res.code === '0') {
				let result = JSON.parse(res.data)
				EventBus.$emit('generateTitle', {
					id: this.chatId,
					title: result.title
				})
			}
		},
		async getAgentInfo() {
			if (this.agentId === xiaoxieGuID) {
				this.agent.suggestionList = this.defaultsuggest
				this.agent.opening = this.defaultopening
			} else {
				let res = await chrome.webview.hostObjects.form.GetAsync(this.agentId)
				res = JSON.parse(res)
				if (res.code === '0') {
					this.agent = Object.assign({}, res.data, { suggestionList: [] })
					try {
						let result = await chrome.webview.hostObjects.chatHelper.OpeningRemarksResult(this.agentId)
						result = JSON.parse(result)
						if (result.code == '0') {
							let sug = JSON.parse(result.data)
							if (sug instanceof Object) {
								let recommends = Object.values(sug)
								this.agent.suggestionList = recommends
							}
						}
					} catch (e) {}
				}
			}
		},
		gotoAgent() {
			this.$router.push({
				name: 'discover_edit',
				query: {
					id: this.agentId
				}
			})
		},
		KeyDownFn(e) {
			if (e.keyCode === 13) {
				e.cancelBubblue = true
				e.stopPropagation()
				e.preventDefault()
				if (e.shiftKey) {
					// shift + 回车
					let sInd = e.srcElement.selectionStart
					let eInd = e.srcElement.selectionEnd
					let val = this.inputStr
					this.inputStr = val.substring(0, sInd) + '\n' + val.substring(eInd)
				} else {
					// 回车
					this.send()
				}
			}
		},
		async delChatDetail(id) {
			await chrome.webview.hostObjects.chatHelper.DeleteChatDetailsAsync(id)
			this.getChatList()
		},
		async initChat() {
			this.list = []
			this.hisList = []
			this.agent = {
				name: '',
				opening: '',
				suggestionList: [],
				role: '',
				welcome: '',
				icon: ''
			}
			await this.getChatList()
		},
		editPrompt(txt) {
			this.currentMsg = txt
		},
		handelAudio(idx) {
			this.list.forEach((item, index) => {
				if (item.chatType === ChatType.robot && index !== idx) {
					this.$refs['robot_' + index][0].setAudioIcon()
				}
			})
		},
		async getInspiration() {
			let res = await chrome.webview.hostObjects.chatHelper.ChatInspirationAsync()
			this.inputStr = res
		},
		setFunctionCall(json) {
			json = JSON.parse(json)
			this.hisList.push({
				chatType: ChatType.functionCall,
				tollcall: json
			})
		}
	},
	mounted() {
		console.log(this.$route.query.id)
		if (this.$route.query.id === undefined) {
			this.chatId = xiaoxieGuID
		} else {
			this.chatId = this.$route.query.id
		}
		if (this.$route.query.type) {
			this.Type = this.$route.query.type
		} else {
			this.Type = 0
		}
		if (this.$route.query.agentId) {
			this.agentId = this.$route.query.agentId
		} else {
			this.agentId = xiaoxieGuID
		}
		setTimeout(async () => {
			await this.initChat()
		}, 0)
		window.receiveMessage = (param) => {
			this.receiveMessage(param)
		}
		window.setVoiceText = (param) => {
			this.setVoiceText(param)
		}
		window.startVoice = () => {
			this.startVoice()
		}
		window.getChatList = () => {
			this.getChatList()
		}
		window.stopRecord = () => {
			this.pauseVoice()
		}
		window.setFunctionCall = (param) => {
			this.setFunctionCall(param)
		}
		this.createClipboardInstance()
	},
	beforeDestroy() {
		if (this.clipboardCode) {
			this.clipboardCode.destroy()
		}
	}
}
</script>
<style lang="less" scoped>
.explore_container {
	.no_chat {
		padding: 3.17rem 5.67rem;
		.logo {
			text-align: center;
			display: flex;
			align-items: center;
			justify-content: center;
			&:hover {
				.logo_right {
					opacity: 1;
				}
			}
			.logo_right {
				background: var(--chat-tool-bg);
				box-shadow: 0rem 0rem 0.42rem 0rem rgba(175, 175, 175, 0.61);
				border-radius: 1rem;
				padding: 1rem;
				padding-right: 0;
				height: 3rem;
				margin-left: 1rem;
				display: flex;
				justify-content: space-between;
				align-items: center;
				opacity: 0;
				span {
					margin-right: 1.5rem;
				}
				/deep/.ivu-poptip-inner {
					background: var(--chat-tool-bg);
				}
				/deep/.ivu-poptip-arrow:after {
					border-right-color: var(--chat-tool-bg);
				}
				.pop_content {
					width: calc(50vw - 21rem);
					white-space: normal;
					overflow: hidden;
					background: var(--chat-tool-bg);
					border: 0.08rem solid var(--chat-tool-bg);
					box-shadow: inset 0.42rem 0.08rem 0.25rem 0rem rgba(255, 255, 255, 0.5);
					box-shadow: 0rem 0rem 0.33rem 0rem rgba(206, 206, 206, 0.71);
					border-radius: 0.67rem 0.67rem 0.67rem 0.67rem 0rem 0.33rem 0rem;
					font-family: PingFangSC-Regular;
					font-size: 1.17rem;
					color: var(--agent-pop-color);
					letter-spacing: 0;
					text-align: left;
					line-height: 2rem;
					font-weight: 400;
					.title {
						font-family: PingFangSC-Semibold;
						font-size: 1.17rem;
						color: var(--agent-pop-title);
						letter-spacing: 0;
						text-align: left;
						font-weight: 600;
						margin-top: 1.33rem;
					}
				}
			}
		}
		.name {
			font-family: PingFangSC-Semibold;
			font-size: 1.33rem;
			color: var(--svg-edit-color);
			letter-spacing: 0;
			text-align: left;
			line-height: 2rem;
			font-weight: 600;
			margin-top: 0.83rem;
			text-align: center;
		}
		.desc {
			background-image: var(--chat-defaultList-bg);
			border-radius: 0.83rem 0.83rem 0.83rem 0rem;
			font-family: PingFangSC-Regular;
			font-size: 1.17rem;
			color: var(--svg-edit-color);
			letter-spacing: 0;
			line-height: 2.33rem;
			font-weight: 400;
			padding: 1.33rem;
			margin-top: 1.58rem;
			margin-bottom: 2.17rem;
		}
		.suggest_list {
			list-style: none;
			li {
				cursor: pointer;
				font-family: PingFangSC-Regular;
				font-size: 14px;
				color: #1890ff;
				letter-spacing: 0;
				line-height: 40px;
				font-weight: 400;
				.dot {
					background: var(--suggest-list-dot);
					border-radius: 0.21rem;
					width: 0.42rem;
					height: 0.42rem;
					display: inline-block;
					vertical-align: middle;
					margin-right: 0.92rem;
				}
			}
		}
	}
	.chat_list {
		margin-top: 2rem;
		height: calc(100vh - 240px);
		overflow: auto;
		padding: 0 5.67rem;
		padding-bottom: 1.2rem;
		.clearContext {
			/deep/.ivu-divider-inner-text {
				color: #aaaaaa;
				font-size: 14px;
			}
		}
	}
	.chat_bottom {
		position: fixed;
		bottom: 0;
		left: 16.67rem;
		width: calc(100vw - 16.67rem);
		padding: 0 5.67rem;
		.tool {
			font-size: 13px;
			color: #aaaaaa;
			display: flex;
			align-items: center;
			.tool_des {
				margin-left: 10px;
			}
			.tool_btn {
				display: flex;
				align-items: center;
				cursor: pointer;
				font-family: PingFangSC-Semibold;
				font-size: 1.13rem;
				color: #f38800;
				letter-spacing: 0;
				font-weight: 600;
				span:first-child {
					margin-right: 0.5rem;
				}
			}
			.tool_right {
				margin-left: auto;
			}
		}
		.input_container {
			margin-top: 1rem;
			position: relative;
			.yuyin {
				position: absolute;
				right: 7.25rem;
				bottom: 1.33rem;
				cursor: pointer;
			}
			/deep/.ivu-input {
				padding: 1.13rem 1.5rem;
				padding-bottom: 2.5rem;
				padding-right: 7.75rem;
				height: 6.63rem;
				opacity: 0.9;
				background: var(--chat-input-bg);
				border: 0.13rem solid var(--chat-input-border);
				box-shadow: inset 0rem 0.06rem 0.44rem 0rem rgba(229, 229, 229, 0.5);
				border-radius: 0.5rem;
				resize: none;
				color: var(--chat-input-color);
			}
		}
		.voice_bg {
			margin-top: 1rem;
			position: relative;
			opacity: 0.9;
			background: var(--chat-input-bg);
			border: 0.13rem solid var(--chat-input-border);
			box-shadow: inset 0rem 0.06rem 0.44rem 0rem rgba(229, 229, 229, 0.5);
			border-radius: 0.5rem;
			min-height: 6.63rem;
			.voice_content {
				padding: 1.13rem 1.5rem 2rem 1.5rem;
				word-wrap: break-word;
				word-break: normal;
			}
			.voice_loading {
				position: absolute;
				bottom: 1.33rem;
				left: calc(50% - 73px);
				span:first-child {
					margin-right: 1rem;
				}
				span {
					font-family: PingFangSC-Regular;
					font-size: 1.13rem;
					color: var(--chat-voice-color);
					letter-spacing: 0;
					font-weight: 400;
				}
			}
			.pausebtn {
				position: absolute;
				right: 7.25rem;
				bottom: 1rem;
				cursor: pointer;
			}
		}
		.bottom_btn {
			position: fixed;
			right: 7rem;
			bottom: 4.33rem;
			/deep/.ivu-btn {
				background-image: linear-gradient(136deg, #ffb346 0%, #fe8e00 100%);
				border-radius: 1.75rem;
				padding: 0.53rem 1.35rem;
				height: 3rem;
				font-size: 1.13rem;
				color: #ffffff;
				font-weight: 600;
				border-color: var(--ivu-btn-border-color);
				border: none;
			}
		}
		.footer {
			text-align: center;
			padding: 0.75rem 0;
			span {
				font-family: PingFangSC-Regular;
				font-size: 1rem;
				color: var(--chat-footer-tips, #c6c6c6);
				letter-spacing: 0;
				font-weight: 400;
			}
		}
	}
}
</style>
